import {Divider, Form, Input, InputNumber} from "antd";
import {RouteDef} from "../model/RouteDef.ts";
import {Kv, ModeProp, RouteDetProp} from "./BaseCompomentDef.tsx";
import {RoutePredicates} from "./RoutePredicate.tsx";
import {RouteMetadataTable} from "./RouteMetadata.tsx";
import {RouteFilterTable} from "./RouteFilter.tsx";


interface RouteBaseInfoProp extends ModeProp , RouteDetProp {

    readOnly? : boolean

    onChangeId? : (id : string) => void

    onChangeUri? : (uri : string) => void

    onChangeOrder? : (order : number ) => void
}

export const RouteBaseInfo = ( prop : RouteBaseInfoProp ) => {
    const id = prop && prop.routeDef && prop.routeDef.id || ''
    const uri = prop && prop.routeDef && prop.routeDef.uri || ''
    const order = prop && prop.routeDef && prop.routeDef.order || 0
    const onChangeId = prop.onChangeId || (() => {  } )
    const onChangeUri = prop.onChangeUri || (() => {  } )
    const onChangeOrder = prop.onChangeOrder || (() => {  } )
    return <>
        <Form >
            <Form.Item required key={0} label="id">
                <Input
                    readOnly={ !(prop.mode === 'create') }
                    value={id}
                    onChange={ (e)=> onChangeId( e.target.value )  }
                />
            </Form.Item>
            <Form.Item required label="uri">
                <Input
                    readOnly={ prop.mode === "display" }
                    value={uri}
                    onChange={(e) => onChangeUri( e.target.value )}
                />
            </Form.Item>
            <Form.Item required label="order" name="order" >
                <InputNumber
                    readOnly={ prop.mode === "display" }
                    required
                    min={0}
                    max={255}
                    defaultValue={order}
                    onChange={(e)=> onChangeOrder( e as number )}
                />
            </Form.Item>
        </Form>
    </>

}






interface RouteDefinitionEditProp extends ModeProp {

    routeDef : RouteDef

    onChange? : ( routeDef : RouteDef ) => void

}


export const RouteDefinitionEdit = (  prop : RouteDefinitionEditProp  ) => {
    const routeDef = { ...prop.routeDef }
    const onChange = prop.onChange || (()=>{})

    const _onChangeId = ( s : string ) => {
        onChange( { ...routeDef , id : s } )
    }

    const _onChangeUri = ( s : string ) => {
        onChange( { ...routeDef , uri : s } )
    }

    const _onChangeOrder = ( n : number ) => {
        onChange( {...routeDef , order : n } )
    }

    const _onAppendPredicate = ( s : string ) => {
        onChange({ ...routeDef , predicates : [...routeDef.predicates , s] })
    }

    const _onModifyPredicate = ( s : string , n  :number ) => {
        const curRouteDef = { ...routeDef , predicates : routeDef.predicates || [] } as RouteDef
        curRouteDef.predicates[n] = s
        onChange( curRouteDef )
    }

    const _onRemovePredicate = ( _ : string , index :number ) => {
        const curRouteDef = { ...routeDef , predicates : routeDef.predicates || [] } as RouteDef
        curRouteDef.predicates = curRouteDef.predicates.filter( ( _ , _index ) => _index !== index )
        onChange( curRouteDef )
    }

    const _onAppendFilter = ( s : string ) => {
        onChange({ ...routeDef , filters : [...routeDef.filters , s] })
    }

    const _onModifyFilter = ( s : string , n  :number ) => {
        const curRouteDef = { ...routeDef , filters : routeDef.filters || [] } as RouteDef
        curRouteDef.filters[n] = s
        onChange( curRouteDef )
    }

    const _onRemoveFilter = ( _ : string , index :number ) => {
        const curRouteDef = { ...routeDef , filters : routeDef.filters || [] } as RouteDef
        curRouteDef.filters = curRouteDef.filters.filter( ( _ , _index ) => _index !== index )
        onChange( curRouteDef )
    }

    const _onAppendMetadata = ( o : Kv ) => {
        const curRouteDef = { ...routeDef , metadata : routeDef.metadata || {} }
        curRouteDef.metadata[o.key] = o.value
        onChange(curRouteDef)
    }

    const _onModifyMetadata = ( o : Kv ) => {
        const curRouteDef = { ...routeDef , metadata : routeDef.metadata || {} }
        curRouteDef.metadata[o.key] = o.value
        onChange(curRouteDef)
    }

    const _onRemoveMetadata = ( o : Kv ) => {
        const curRouteDef = { ...routeDef , metadata : routeDef.metadata || {} }
        delete curRouteDef.metadata[o.key]
        onChange(curRouteDef)
    }


    return <>
        <RouteBaseInfo
            routeDef={ routeDef }
            mode={ prop.mode }
            onChangeId={ _onChangeId }
            onChangeUri={ _onChangeUri }
            onChangeOrder={ _onChangeOrder }
        />
        <Divider></Divider>
        <RoutePredicates
            mode={ prop.mode }
            predicates={ routeDef.predicates }
            onAppendPredicate={ _onAppendPredicate }
            onModifyPredicate={ _onModifyPredicate }
            onRemovePredicate={ _onRemovePredicate }
        />
        <Divider></Divider>
        <RouteMetadataTable
            mode={ prop.mode }
            metadata={ routeDef.metadata }
            onAppend={ _onAppendMetadata }
            onModify={ _onModifyMetadata }
            onRemove={ _onRemoveMetadata }
        />
        <Divider></Divider>
        <RouteFilterTable
            mode={ prop.mode }
            filters={ routeDef.filters }
            onAppendFilter={ _onAppendFilter }
            onModifyFilter={ _onModifyFilter }
            onRemoveFilter={ _onRemoveFilter }
        />
    </>

}

